home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / GrowBoxDock / Sources / PICTFile.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-30  |  26.6 KB  |  932 lines

  1. /*
  2.     File:        PICTFile.c
  3.  
  4.     Contains:    PICT file for simple text application
  5.  
  6.     Version:    Mac OS X
  7.  
  8.     Disclaimer:    IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
  9.                 ("Apple") in consideration of your agreement to the following terms, and your
  10.                 use, installation, modification or redistribution of this Apple software
  11.                 constitutes acceptance of these terms.  If you do not agree with these terms,
  12.                 please do not use, install, modify or redistribute this Apple software.
  13.  
  14.                 In consideration of your agreement to abide by the following terms, and subject
  15.                 to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
  16.                 copyrights in this original Apple software (the "Apple Software"), to use,
  17.                 reproduce, modify and redistribute the Apple Software, with or without
  18.                 modifications, in source and/or binary forms; provided that if you redistribute
  19.                 the Apple Software in its entirety and without modifications, you must retain
  20.                 this notice and the following text and disclaimers in all such redistributions of
  21.                 the Apple Software.  Neither the name, trademarks, service marks or logos of
  22.                 Apple Computer, Inc. may be used to endorse or promote products derived from the
  23.                 Apple Software without specific prior written permission from Apple.  Except as
  24.                 expressly stated in this notice, no other rights or licenses, express or implied,
  25.                 are granted by Apple herein, including but not limited to any patent rights that
  26.                 may be infringed by your derivative works or by other works in which the Apple
  27.                 Software may be incorporated.
  28.  
  29.                 The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
  30.                 WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  31.                 WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  32.                 PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  33.                 COMBINATION WITH YOUR PRODUCTS.
  34.  
  35.                 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  36.                 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  37.                 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.                 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
  39.                 OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
  40.                 (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
  41.                 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42.  
  43.     Copyright © 1993-2001 Apple Computer, Inc., All Rights Reserved
  44. */
  45.  
  46. #include "MacIncludes.h"
  47.  
  48. #if defined(USE_UMBRELLA_HEADERS) && USE_UMBRELLA_HEADERS
  49. #include <QuickTime.h>
  50. #else
  51. #include "ImageCompression.h"
  52. // #include "GraphicsImporter.h"
  53. #endif
  54.  
  55. #include "PICTFile.h"
  56.  
  57. /* ------------------------------------------------------------------------------------    */
  58. /* GLOBALS ONLY USED BY THIS FILE */
  59. /* ------------------------------------------------------------------------------------    */
  60. #define kBufferSize    2048
  61.  
  62. static short            gPictFileRefNum;
  63. static char                gPictureBuffer[kBufferSize];
  64. static long                gAmountInBuffer;
  65. static long                gFirstCharInBuffer;
  66. //static QDProcsPtr         gSavedProcs;
  67. static QDProcs            gMyProcs;
  68. static CQDProcs           gMyColorProcs;
  69.  
  70. // --------------------------------------------------------------------------------------------------------------
  71. // INTERNAL ROUTINES
  72. // --------------------------------------------------------------------------------------------------------------
  73.  
  74. static pascal void GetPICTData(Ptr dataPtr,short byteCount)
  75. /*
  76.     replacement for the QuickDraw bottleneck routine
  77. */
  78.     OSStatus            err = noErr;
  79.     long            longCount;
  80.  
  81.     longCount = byteCount;
  82.     
  83.     while ( (longCount > 0) && (err == noErr) )
  84.         {
  85.         if (gAmountInBuffer == 0)
  86.             {
  87.             gAmountInBuffer = kBufferSize;
  88.             gFirstCharInBuffer = 0;
  89.             err = FSRead(gPictFileRefNum,&gAmountInBuffer,gPictureBuffer);
  90.             }
  91.  
  92.         if (gAmountInBuffer > 0)
  93.             {
  94.             long    amountToMove;
  95.             
  96.             amountToMove = gAmountInBuffer;
  97.             if (amountToMove > longCount)
  98.                 amountToMove = longCount;
  99.                 
  100.             BlockMoveData(&gPictureBuffer[gFirstCharInBuffer], dataPtr, amountToMove);
  101.             longCount -= amountToMove;
  102.             dataPtr += amountToMove;
  103.             gFirstCharInBuffer += amountToMove;
  104.             gAmountInBuffer -= amountToMove;
  105.             }
  106.             
  107.         }
  108.     
  109. } // GetPICTData
  110.  
  111.  
  112. // --------------------------------------------------------------------------------------------------------------
  113.  
  114. static OSStatus    DiskPictureDraw( WindowDataPtr pData, 
  115.     Boolean doDraw, Rect *pictureRect, Point *pOffset)
  116. {
  117.  
  118.     OSStatus        anErr;
  119.     PicHandle    picHandle;
  120.     Point        offset;
  121.     
  122.     if (pOffset)
  123.         offset = *pOffset;
  124.     else
  125.         {
  126.         offset.h = GetControlValue(pData->hScroll);
  127.         offset.v = GetControlValue(pData->vScroll);
  128.         }
  129.  
  130. #if ALLOW_QUICKTIME
  131.     if( ((PICTDataPtr)pData)->isQuickTimeImageFile )
  132.         {
  133.         GraphicsImportComponent theGraphicsImporter = 0;
  134.         
  135.         anErr = GetGraphicsImporterForFile( &pData->fileSpec, &theGraphicsImporter );
  136.         
  137.         if( noErr == anErr )
  138.             {
  139.             anErr = GraphicsImportSetQuality(
  140.                             theGraphicsImporter, 
  141.                             codecHighQuality );
  142.             }
  143.         
  144.         if( noErr == anErr )
  145.             {
  146.             Rect    destRect = ((PICTDataPtr)pData)->pictureRectangle;
  147.             
  148.             OffsetRect(&destRect, 
  149.                                 -destRect.left + 
  150.                                     pData->contentRect.left -
  151.                                     offset.h, 
  152.                                 -destRect.top + 
  153.                                     pData->contentRect.top -
  154.                                     offset.v);
  155.  
  156.             anErr = GraphicsImportSetBoundsRect( theGraphicsImporter, &destRect ); 
  157.             }
  158.         
  159.         if( noErr == anErr )
  160.             {
  161.             RgnHandle    theGripClip = NewRgn();
  162.             RectRgn( theGripClip, &pData->contentRect );
  163.             anErr = GraphicsImportSetClip( theGraphicsImporter, theGripClip );
  164.             DisposeRgn( theGripClip );
  165.             }
  166.         
  167.         if( noErr == anErr )
  168.             {
  169.             anErr = GraphicsImportDraw( theGraphicsImporter );
  170.             }
  171.         
  172.         if( 0 != theGraphicsImporter )
  173.             {
  174.             CloseComponent( theGraphicsImporter );
  175.             }
  176.         
  177.         return anErr;
  178.         }
  179. #endif
  180.  
  181.     picHandle = ((PICTDataPtr)pData)->cacheHandle;
  182.     
  183.     if (picHandle)
  184.         {
  185.  
  186.  
  187.         if (doDraw)
  188.             {
  189.             Rect    destRect;
  190.             
  191.             GetPICTRectangleAt72dpi(picHandle, &destRect);
  192.  
  193.             OffsetRect(&destRect, 
  194.                                 -destRect.left + 
  195.                                     pData->contentRect.left -
  196.                                     offset.h, 
  197.                                 -destRect.top + 
  198.                                     pData->contentRect.top -
  199.                                     offset.v);
  200.             DrawPicture(picHandle, &destRect);
  201.             }
  202.         
  203.         if (pictureRect)
  204.             {
  205.             GetPICTRectangleAt72dpi(picHandle, pictureRect);
  206.             OffsetRect(pictureRect, -pictureRect->left, -pictureRect->top);
  207.             }
  208.             
  209.         picHandle = nil;
  210.         anErr = noErr;
  211.         }
  212.     else
  213.         {
  214.         // make enough room for PICT header, including version
  215.         picHandle = (PicHandle) NewHandle(sizeof(Picture)  + sizeof(long)*8);
  216.         anErr = MemError();
  217.         nrequire(anErr, FailedNewHandle);
  218.         
  219.         gPictFileRefNum = pData->dataRefNum;
  220.         anErr = SetFPos(gPictFileRefNum, fsFromStart, 512);
  221.         nrequire(anErr, FailedSetFPos);
  222.         
  223.         gAmountInBuffer = kBufferSize;
  224.         gFirstCharInBuffer = 0;
  225.         anErr = FSRead(gPictFileRefNum, &gAmountInBuffer, gPictureBuffer);
  226.         if (anErr == eofErr)
  227.             anErr = noErr;
  228.         if (gAmountInBuffer < sizeof(Picture))
  229.             anErr = eofErr;
  230.         nrequire(anErr, FailedInitialRead);
  231.     
  232.         // copy PICT header, including version
  233.         BlockMoveData(gPictureBuffer, *picHandle, sizeof(Picture) + sizeof(long)*8);
  234.         gFirstCharInBuffer += sizeof(Picture);
  235.         gAmountInBuffer -= sizeof(Picture);
  236.         
  237.         if (doDraw)
  238.             {
  239.             Rect    destRect;
  240. #if USE_QD_GRAFPROCS
  241.             CGrafPtr thePort = GetQDGlobalsThePort();
  242. #endif
  243.             
  244.             GetPICTRectangleAt72dpi(picHandle, &destRect);
  245.             if (!gMachineInfo.haveQuickTime)
  246.                 {
  247.                 static QDGetPicUPP gGetPICTData = NULL;
  248. #if USE_QD_GRAFPROCS
  249.                 CQDProcs gprocs;
  250. #endif
  251.  
  252.                 if (!gGetPICTData) {
  253.                     gGetPICTData = NewQDGetPicUPP(GetPICTData);
  254.                 }
  255.  
  256. #if USE_QD_GRAFROCS
  257.                 if (GetPortGrafProcs(thePort, &gprocs))
  258.                     SetPortGrafProcs(thePort, &gMyColorProcs);
  259.                 else
  260.                     SetStdCProcs(&gMyColorProcs);
  261. #endif
  262.                 gMyProcs.getPicProc = gGetPICTData;
  263.                 gMyColorProcs.getPicProc = gGetPICTData;
  264.                 }
  265.                 
  266.             OffsetRect(&destRect, -destRect.left +                         pData->contentRect.left - offset.h, 
  267.                 -destRect.top + pData->contentRect.top -
  268.                 offset.v);
  269.                                                 
  270.             if (!gMachineInfo.haveQuickTime)
  271.                 {
  272.                 DrawPicture(picHandle, &destRect);
  273.                 }
  274. #if ALLOW_QUICKTIME
  275.             else
  276.                 DrawPictureFile(gPictFileRefNum, &destRect, nil);
  277. #endif
  278.             }
  279.             
  280.         if (pictureRect)
  281.             {
  282.             GetPICTRectangleAt72dpi(picHandle, pictureRect);
  283.             OffsetRect(pictureRect, -pictureRect->left, 
  284.                     -pictureRect->top);
  285.             }
  286.         }
  287.     
  288. // FALL THROUGH EXCEPTION HANDLING
  289. FailedInitialRead:
  290. FailedSetFPos:
  291.     DisposeHandle((Handle) picHandle);
  292.  
  293. FailedNewHandle:
  294.     
  295.     return(anErr);
  296.         
  297. } // DiskPictureDraw
  298.  
  299. // --------------------------------------------------------------------------------------------------------------
  300. static OSStatus GetSelectedPicture(WindowDataPtr pData, PicHandle *pResult)
  301. {
  302.     OSStatus        anErr;
  303.     PicHandle    scrapPict;
  304.     Rect        globRect;
  305.     GDHandle    theMaxDevice;
  306.     short        theDepth;
  307.     GDHandle    savedGDevice;
  308.     CGrafPtr    savedPort;
  309.     GWorldPtr    offscreenGWorld;
  310.         RgnHandle    visRgn;
  311.     Rect        bounds;
  312.         PixMapHandle    bMap;
  313.  
  314.     // save away current value for restores
  315.     GetGWorld(&savedPort, &savedGDevice);
  316.  
  317.     // determine the best way in which to allocate stuff
  318.     
  319.     SetRect(&globRect, -32760, -32760, 32760, 32760);
  320.  
  321.     theDepth = 8;
  322.     theMaxDevice = GetMaxDevice(&globRect);
  323.     if (theMaxDevice != nil)
  324.         theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
  325.     
  326.     // allocate the GWorld in temp mem, or local if we run out
  327.     anErr = NewGWorld(&offscreenGWorld, theDepth, 
  328.                         &((PICTDataPtr)pData)->selectionRectangle,
  329.                         nil, nil, useTempMem);
  330.     if (anErr != noErr)
  331.         anErr = NewGWorld(&offscreenGWorld, theDepth, 
  332.                             &((PICTDataPtr)pData)->selectionRectangle,
  333.                             nil, nil, 0);
  334.     nrequire(anErr, FailedNewGWorld);
  335.  
  336.     // blow open the visRgn, and clip to the selected area
  337.     visRgn = NewRgn();
  338.     GetPortVisibleRegion(offscreenGWorld, visRgn);
  339.     RectRgn(visRgn, &globRect);
  340.     DisposeRgn(visRgn);
  341.     PortChanged(offscreenGWorld);
  342.     SetGWorld(offscreenGWorld, nil);
  343.     EraseRect(GetPortBounds(offscreenGWorld, &bounds));
  344.     ClipRect(&((PICTDataPtr)pData)->selectionRectangle);
  345.     
  346.     // Draw the picture into the offscreen
  347.     LockPixels( GetGWorldPixMap(offscreenGWorld));
  348.     {
  349.     Point    offset = {0,0};
  350.     anErr = DiskPictureDraw(pData, true, nil, &offset);
  351.     }
  352.     UnlockPixels( GetGWorldPixMap(offscreenGWorld));
  353.     nrequire(anErr, FailedDraw);
  354.  
  355.     // CopyBits in place to grab the selection
  356.     scrapPict = OpenPicture(&((PICTDataPtr)pData)->selectionRectangle);
  357.     LockPixels( GetGWorldPixMap(offscreenGWorld));
  358.         bMap = GetPortPixMap(offscreenGWorld);
  359.     CopyBits((BitMap *)*bMap, (BitMap *)*bMap, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->selectionRectangle, srcCopy, nil);
  360.     anErr = QDError();
  361.     UnlockPixels( GetGWorldPixMap(offscreenGWorld));
  362.     ClosePicture();
  363.     globRect = (**scrapPict).picFrame;
  364.     if ( (anErr == noErr) && (EmptyRect(&globRect)) )
  365.         anErr = memFullErr;
  366.         
  367.     // done with our offscreen now
  368.     SetGWorld(savedPort, savedGDevice);
  369.     DisposeGWorld(offscreenGWorld);
  370.  
  371.     if (anErr == noErr)
  372.         *pResult = scrapPict;
  373.     
  374.     return(anErr);
  375.     
  376. // EXCEPTION HANDLING
  377. FailedDraw:
  378.     DisposeGWorld(offscreenGWorld);
  379.     
  380. FailedNewGWorld:
  381.  
  382.     SetGWorld(savedPort, savedGDevice);
  383.     return(anErr);
  384.     
  385. } // GetSelectedPicture
  386.  
  387. // --------------------------------------------------------------------------------------------------------------
  388. static OSStatus CopyGWorld(WindowDataPtr pData)
  389. {
  390.     OSStatus    anErr;
  391.     PicHandle    scrapPict;
  392.     ScrapRef    scrap;
  393.  
  394.     anErr = GetSelectedPicture(pData, &scrapPict);
  395.  
  396.     if (!anErr)
  397.     {
  398.         do
  399.         {
  400.             if (anErr) break;
  401.             anErr = ClearCurrentScrap ( );
  402.             if (anErr) break;
  403.             anErr = GetCurrentScrap (&scrap);
  404.             MoveHHi ((Handle) scrapPict);
  405.             anErr = MemError ( );
  406.             if (anErr) break;
  407.             HLock ((Handle) scrapPict);
  408.             anErr = MemError ( );
  409.             if (anErr) break;
  410.             anErr = PutScrapFlavor (scrap, 'PICT', 0, GetHandleSize((Handle) scrapPict), *scrapPict);
  411.             if (anErr) break;
  412.         }
  413.         while (false);
  414.  
  415.         KillPicture(scrapPict);
  416.     }
  417.  
  418.     return anErr;
  419.     
  420. } // CopyGWorld
  421.  
  422. // --------------------------------------------------------------------------------------------------------------
  423. static pascal OSErr PICTSendDataProc(FlavorType theType, void *dragSendRefCon,
  424.                                 ItemReference theItem, DragReference theDrag)
  425. /*
  426.  *    The ItemReference is the gxShape to be sent. The dragSendRefCon is ignored.
  427. */
  428. {
  429. #pragma unused (theItem)
  430.  
  431.     OSStatus    result = noErr;
  432.  
  433.     switch (theType) 
  434.         {
  435.         case 'PICT':
  436.             {    
  437.             PicHandle     pict;
  438.             OSStatus        anErr = GetSelectedPicture((WindowDataPtr)dragSendRefCon, &pict);
  439.     
  440.             if (anErr == noErr)
  441.                 {    
  442.                 HLock((Handle)pict);
  443.                 result = SetDragItemFlavorData(theDrag, 1, 'PICT', (Ptr)*pict, GetHandleSize((Handle)pict), 0);
  444.                 KillPicture(pict);
  445.                 }
  446.             }
  447.             break;
  448.             
  449.         default:
  450.             result = badDragFlavorErr;
  451.             break;
  452.         }
  453.         
  454.     return result;
  455.     
  456. } // PICTSendDataProc
  457.  
  458.  
  459. // --------------------------------------------------------------------------------------------------------------
  460. // OOP INTERFACE ROUTINES
  461. // --------------------------------------------------------------------------------------------------------------
  462.  
  463. static OSStatus    PICTUpdateWindow(WindowPtr pWindow, WindowDataPtr pData)
  464. {
  465.     OSStatus        anErr;
  466.     RgnHandle    oldClip = NewRgn();
  467.     
  468.     EraseRect(&pData->contentRect);
  469.     
  470.     GetClip(oldClip);
  471.     ClipRect(&pData->contentRect);
  472.     anErr = DiskPictureDraw( pData, true, nil, nil);
  473.     SetClip(oldClip);
  474.     DisposeRgn(oldClip);
  475.     
  476.     DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, false);
  477.     
  478.     DrawControls(pWindow);
  479.     DrawGrowIcon(pWindow);
  480.     
  481.     return(anErr);
  482.     
  483. } // PICTUpdateWindow
  484.  
  485. // --------------------------------------------------------------------------------------------------------------
  486.  
  487. static OSStatus    PICTGetDocumentRect(WindowPtr pWindow, WindowDataPtr pData, 
  488.             LongRect * documentRectangle, Boolean forGrow)
  489. {
  490. #pragma unused (pWindow, forGrow)
  491.  
  492.     RectToLongRect(&((PICTDataPtr)pData)->pictureRectangle, documentRectangle);
  493.     
  494.     return(noErr);
  495.     
  496. } // PICTGetDocumentRect
  497.  
  498. // --------------------------------------------------------------------------------------------------------------
  499.  
  500. static OSStatus    PICTCloseWindow(WindowPtr pWindow, WindowDataPtr pData)
  501. {
  502. #pragma unused (pWindow)
  503.  
  504.     DisposeHandle( (Handle) (((PICTDataPtr)pData)->cacheHandle));
  505.     
  506.     return(noErr);
  507.     
  508. } // PICTCloseWindow
  509.  
  510. // --------------------------------------------------------------------------------------------------------------
  511.  
  512. static OSStatus    PICTContentClick(WindowPtr pWindow, WindowDataPtr pData, EventRecord *pEvent)
  513. {
  514.     OSStatus            anErr = noErr;
  515.     Rect            selectionRect = ((PICTDataPtr)pData)->selectionRectangle;
  516.     Point            clickPoint = pEvent->where;
  517.     ControlHandle    theControl;
  518.     
  519.     GlobalToLocal(&clickPoint);
  520.     if (FindControl(clickPoint, pWindow, &theControl) == 0)
  521.         {
  522.         OffsetRect(&selectionRect, -GetControlValue(pData->hScroll), -GetControlValue(pData->vScroll));
  523.         if ( (gMachineInfo.haveDragMgr) && (PtInRect(clickPoint, &selectionRect)) )
  524.             {
  525.             DragAndDropArea(pWindow, pData, pEvent, 
  526.                                 &selectionRect);
  527.             }
  528.         else
  529.             {
  530.             anErr = SelectContents(pWindow, pData, pEvent, 
  531.                         &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->pictureRectangle, 
  532.                         &((PICTDataPtr)pData)->patternPhase);
  533.             }
  534.         }
  535.     
  536.     return(anErr);
  537.     
  538. } // PICTContentClick
  539.  
  540. // --------------------------------------------------------------------------------------------------------------
  541.  
  542. static OSStatus    PICTAdjustCursor(WindowPtr pWindow, WindowDataPtr pData, Point * localMouse, RgnHandle globalRgn)
  543. {
  544. #pragma unused (pWindow)
  545.  
  546.     OSStatus            anErr = noErr;
  547.     CursHandle        theCross;
  548.     Rect            selectionRect = ((PICTDataPtr)pData)->selectionRectangle;
  549.     Rect            globalSelection;
  550.     
  551.     OffsetRect(&selectionRect, -GetControlValue(pData->hScroll), -GetControlValue(pData->vScroll));
  552.     
  553.     globalSelection = selectionRect;
  554.     LocalToGlobal(&TopLeft(globalSelection));
  555.     LocalToGlobal(&BotRight(globalSelection));
  556.     
  557.     if (!PtInRect(*localMouse, &selectionRect) )
  558.         {
  559.         theCross = MacGetCursor(crossCursor);
  560.         if (theCross)
  561.             {
  562.             char    oldState;
  563.             
  564.             oldState = HGetState((Handle) theCross);
  565.             HLock((Handle) theCross);
  566.             SetCursor(*theCross);
  567.             HSetState((Handle) theCross, oldState);
  568.             anErr = eActionAlreadyHandled;
  569.             }
  570.             
  571.         // make sure we get mouse-moved events if the mouse moves into the selection rect,
  572.         // so that we can change the cursor
  573.         if (!EmptyRect(&globalSelection))
  574.             {    
  575.             RgnHandle    tempRgn = NewRgn();
  576.             
  577.             RectRgn(tempRgn, &globalSelection);
  578.             DiffRgn(globalRgn, tempRgn, globalRgn);
  579.             DisposeRgn(tempRgn);
  580.             }
  581.         }
  582.     else
  583.         {
  584.         // if we're already in the selection rect, we don't need mouse-moved events as long
  585.         // as we stay there
  586.         RectRgn(globalRgn, &globalSelection);
  587.         }
  588.         
  589.     return(anErr);
  590.     
  591. } // PICTAdjustCursor
  592.  
  593. // --------------------------------------------------------------------------------------------------------------
  594.  
  595. static OSStatus    PICTDragAddFlavors(WindowPtr pWindow, WindowDataPtr pData, DragReference theDragRef)
  596. {
  597. #pragma unused (pWindow)
  598.  
  599.     static DragSendDataUPP gPICTSendDataProc = NULL;
  600.     OSStatus    anErr = noErr;
  601.     
  602.     if (!gPICTSendDataProc) {
  603.         gPICTSendDataProc = NewDragSendDataUPP(PICTSendDataProc);
  604.     }
  605.     SetDragSendProc(theDragRef, gPICTSendDataProc, pData);
  606.     AddDragItemFlavor(theDragRef, 1, 'PICT', nil, 0, 0);
  607.     
  608.     return(anErr);
  609.     
  610. } // PICTDragAddFlavors
  611.  
  612. // --------------------------------------------------------------------------------------------------------------
  613.  
  614. static OSStatus    PICTGetBalloon(WindowPtr pWindow, WindowDataPtr pData, 
  615.         Point *localMouse, short * returnedBalloonIndex, Rect *returnedRectangle)
  616. {
  617. #pragma unused (pWindow, pData)
  618.  
  619.     Rect    tempRect = ((PICTDataPtr)pData)->selectionRectangle;
  620.     
  621.     // assume generic content
  622.     *returnedBalloonIndex = iHelpPictContent;
  623.     
  624.     // see if we are within the selection
  625.     OffsetRect(&tempRect, -GetControlValue(pData->hScroll), -GetControlValue(pData->vScroll) );
  626.     SectRect(&tempRect, &pData->contentRect, &tempRect);
  627.     
  628.     if (PtInRect(*localMouse, &tempRect))
  629.         {
  630.         *returnedRectangle        = tempRect;
  631.         *returnedBalloonIndex     = iHelpPictSelection;
  632.         }
  633.         
  634.     return(noErr);
  635.     
  636. } // PICTGetBalloon
  637.  
  638. // --------------------------------------------------------------------------------------------------------------
  639.  
  640. static OSStatus    PICTPrintPage(WindowPtr pWindow, WindowDataPtr pData,
  641.                     Rect * pageRect, long *pageNum)
  642. {
  643. #pragma unused (pWindow)
  644.  
  645.     OSStatus    anErr = noErr;
  646.     short    pagesWide, pagesHigh;
  647.     Rect    pictureRect = ((PICTDataPtr)pData)->pictureRectangle;
  648.     Point    offset;
  649.     Rect    localPageRect = *pageRect;
  650.     
  651.     // calculate how many physical pages will be required to print this PICT
  652.     if (EqualRect(&pictureRect, &localPageRect))
  653.         pagesWide = pagesHigh = 1;
  654.     else
  655.         {
  656.         pagesWide = (pictureRect.right - pictureRect.left) / (localPageRect.right - localPageRect.left) + 1;
  657.         pagesHigh = (pictureRect.bottom - pictureRect.top) / (localPageRect.bottom - localPageRect.top) + 1;
  658.         }
  659.                     
  660.     // compute the offset in # of pages
  661.     offset.h = ((*pageNum - 1) % pagesWide);
  662.     offset.v = ((*pageNum - 1) / pagesWide);
  663.  
  664.     // compute the pixel offset for this page
  665.     offset.h *= localPageRect.right - localPageRect.left;
  666.     offset.v *= localPageRect.bottom - localPageRect.top;
  667.     
  668.     anErr = DiskPictureDraw( pData, true, &localPageRect, &offset);
  669.     
  670.     // tell it to stop printing when we reach the end
  671.     if (*pageNum >= (pagesWide*pagesHigh))
  672.         *pageNum = -1;
  673.     
  674.     return(anErr);
  675.     
  676. } // PICTPrintPage
  677.  
  678. // --------------------------------------------------------------------------------------------------------------
  679.  
  680. static OSStatus    PICTAdjustMenus(WindowPtr pWindow, WindowDataPtr pData)
  681. {
  682. #pragma unused (pWindow)
  683.  
  684.     OSStatus anErr = noErr;
  685.     
  686.     if (!EmptyRect(&((PICTDataPtr)pData)->selectionRectangle))
  687.         EnableCommand(cCopy);
  688.  
  689.     if     (EqualRect(&((PICTDataPtr)pData)->pictureRectangle, &((PICTDataPtr)pData)->selectionRectangle))
  690.         ChangeCommandName(cSelectAll, kMiscStrings, iSelectNoneCommand);
  691.     else
  692.         ChangeCommandName(cSelectAll, kMiscStrings, iSelectAllCommand);
  693.     EnableCommand(cSelectAll);
  694.     
  695.     return(anErr);
  696.     
  697. } // PICTAdjustMenus
  698.  
  699. // --------------------------------------------------------------------------------------------------------------
  700.  
  701. static OSStatus PICTCommand(WindowPtr pWindow, WindowDataPtr pData, short commandID, long menuResult)
  702. {
  703. #pragma unused (pWindow, menuResult)
  704.  
  705.     OSStatus anErr = noErr;
  706.     
  707.     switch (commandID)
  708.         {
  709.         case cCopy:
  710.             anErr = CopyGWorld(pData);
  711.             break;
  712.         
  713.         case cSelectAll:
  714.             // erase the old selection
  715.             DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, false);
  716.             
  717.             if     (EqualRect(&((PICTDataPtr)pData)->pictureRectangle, &((PICTDataPtr)pData)->selectionRectangle))
  718.                 {
  719.                 ((PICTDataPtr)pData)->selectionRectangle.top = 0;
  720.                 ((PICTDataPtr)pData)->selectionRectangle.left = 0;
  721.                 ((PICTDataPtr)pData)->selectionRectangle.bottom = 0;
  722.                 ((PICTDataPtr)pData)->selectionRectangle.right = 0;
  723.                 }
  724.             else
  725.                 {
  726.                 ((PICTDataPtr)pData)->selectionRectangle = ((PICTDataPtr)pData)->pictureRectangle;
  727.                 }
  728.                 
  729.             // draw the new selection
  730.             DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, true);
  731.             
  732.             DoAdjustCursor(pWindow, nil);
  733.             break;
  734.         }
  735.     
  736.     return(anErr);
  737.     
  738. } // PICTCommand
  739.  
  740. // --------------------------------------------------------------------------------------------------------------
  741.  
  742. static long PICTCalculateIdleTime(WindowPtr pWindow, WindowDataPtr pData)
  743. {
  744. #pragma unused (pWindow)
  745.  
  746.     if (!EmptyRect( &((PICTDataPtr)pData)->selectionRectangle))
  747.         return(0);
  748.     else
  749.         return(kMaxWaitTime);
  750.         
  751. } // PICTCalculateIdleTime
  752.  
  753. // --------------------------------------------------------------------------------------------------------------
  754.  
  755. static Boolean    PICTFilterEvent(WindowPtr pWindow, WindowDataPtr pData, EventRecord *pEvent)
  756. {
  757.     if     (
  758.         (!gMachineInfo.amInBackground) &&
  759.         (pEvent->what == nullEvent) &&
  760.         (pWindow == FrontWindow()) &&
  761.         //(EmptyRgn( ((WindowPeek)pWindow)->updateRgn)) &&
  762.         (MOVESELECTION(pEvent->when) )
  763.         )
  764.         {
  765.         // erase the old
  766.         DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, false);
  767.         
  768.         // draw the new, moving onto the next pattern
  769.         DrawSelection(pData, &((PICTDataPtr)pData)->selectionRectangle, &((PICTDataPtr)pData)->patternPhase, true);
  770.         }
  771.         
  772.     return(false);
  773.     
  774. } // PICTFilterEvent
  775.  
  776. // --------------------------------------------------------------------------------------------------------------
  777.  
  778. static OSStatus    PICTMakeWindow(WindowPtr pWindow, WindowDataPtr pData)
  779. {
  780. #pragma unused (pWindow)
  781.  
  782.     Size    availableRAM;
  783.     long    amountInFile;
  784.     OSStatus    anErr = noErr;
  785.     Cursor    arrow;
  786.  
  787.     pData->pUpdateWindow         = (UpdateWindowProc)        PICTUpdateWindow;
  788.     pData->pGetDocumentRect     = (GetDocumentRectProc)        PICTGetDocumentRect;
  789.     pData->pCloseWindow         = (CloseWindowProc)            PICTCloseWindow;
  790.     pData->pContentClick         = (ContentClickProc)        PICTContentClick;
  791.     pData->pAdjustCursor         = (AdjustCursorProc)        PICTAdjustCursor;
  792.     pData->pGetBalloon             = (GetBalloonProc)            PICTGetBalloon;
  793.     pData->pAdjustMenus         = (AdjustMenusProc)            PICTAdjustMenus;
  794.     pData->pPrintPage             = (PrintPageProc)            PICTPrintPage;
  795.     pData->pCommand                 = (CommandProc)                PICTCommand;
  796.     pData->pFilterEvent             = (FilterEventProc)            PICTFilterEvent;
  797.     pData->pCalculateIdleTime    = (CalculateIdleTimeProc)    PICTCalculateIdleTime;
  798.     pData->pDragAddFlavors        = (DragAddFlavorsProc)        PICTDragAddFlavors;
  799.  
  800.     pData->hasGrow                = true;
  801.     pData->hScrollAmount        = 10;
  802.     pData->vScrollAmount        = 10;
  803.  
  804.     ((PICTDataPtr)pData)->isQuickTimeImageFile = ( pData->originalFileType != 'PICT' );
  805.  
  806. #if ALLOW_QUICKTIME
  807.  
  808.     if( ((PICTDataPtr)pData)->isQuickTimeImageFile )
  809.         {
  810.         GraphicsImportComponent theGraphicsImporter;
  811.  
  812.         if (pData->dataRefNum != -1)
  813.             {
  814.             FSClose(pData->dataRefNum);
  815.             pData->dataRefNum = -1;
  816.             }
  817.  
  818.         SetPort( GetWindowPort(pWindow) );
  819.         anErr = GetGraphicsImporterForFile( &pData->fileSpec, &theGraphicsImporter );
  820.         if( noErr == anErr )
  821.             {
  822.             anErr = GraphicsImportGetNaturalBounds( theGraphicsImporter, &((PICTDataPtr)pData)->pictureRectangle );
  823.             CloseComponent( theGraphicsImporter );
  824.             }
  825.         }
  826.     else
  827. #endif
  828.     {
  829.         // Calculate amount of available RAM for cache
  830.         {
  831.             Size grow;
  832.             availableRAM = MaxMem(&grow);
  833.         }
  834.  
  835.         // Take half of it
  836.         availableRAM >>= 1;
  837.  
  838.         // if too big, make it just big enough
  839.         GetEOF(pData->dataRefNum, &amountInFile);
  840.         amountInFile -= 512;
  841.  
  842.         SetWatchCursor();
  843.  
  844.         if (amountInFile < sizeof(Picture))
  845.         {
  846.             anErr = eErrorWhileDrawing;
  847.         }
  848.         else
  849.         {
  850.             if (availableRAM > amountInFile)
  851.             {
  852.                 Handle    theHandle = NewHandle(amountInFile);
  853.  
  854.                 if (theHandle)
  855.                 {
  856.                     SetFPos(pData->dataRefNum, fsFromStart, 512);
  857.                     FSRead(pData->dataRefNum, &amountInFile, *theHandle);
  858.  
  859.                     ((PICTDataPtr)pData)->cacheHandle = (PicHandle)theHandle;
  860.                 }
  861.             }
  862.             
  863.             // initialize the rectangle to be valid
  864.             DiskPictureDraw( pData, false, &((PICTDataPtr)pData)->pictureRectangle, nil);
  865.  
  866.         }
  867.            SetCursor(GetQDGlobalsArrow(&arrow));
  868.     }
  869.     
  870.     if (anErr == noErr)
  871.     {
  872.         Rect    pictureRect;
  873.  
  874.         pictureRect = ((PICTDataPtr)pData)->pictureRectangle;
  875.  
  876.         if ((pData->contentRect.right > pictureRect.right) && (pictureRect.right > 0))
  877.             pData->contentRect.right = pictureRect.right;
  878.         if ((pData->contentRect.bottom > pictureRect.bottom) && (pictureRect.bottom > 0))
  879.             pData->contentRect.bottom = pictureRect.bottom;
  880.  
  881.         // proportional scrolling
  882.         if( gMachineInfo.haveProxyIcons )
  883.             {
  884.             SetControlViewSize( pData->hScroll, pictureRect.right - pictureRect.left );
  885.             SetControlViewSize( pData->vScroll, pictureRect.bottom - pictureRect.top );
  886.             }
  887.         }
  888.  
  889.     return(anErr);
  890.  
  891. } // PICTMakeWindow
  892.  
  893.  
  894. // --------------------------------------------------------------------------------------------------------------
  895.  
  896. OSStatus    PICTPreflightWindow(PreflightPtr pPreflightData)
  897. {
  898.     pPreflightData->wantHScroll            = true;
  899.     pPreflightData->wantVScroll            = true;
  900.  
  901.     pPreflightData->continueWithOpen     = true;
  902.     pPreflightData->makeProcPtr         = PICTMakeWindow;
  903.  
  904.     pPreflightData->storageSize = sizeof(PICTDataRecord);
  905.  
  906.     return(noErr);
  907.  
  908. } // PICTPreflightWindow
  909.  
  910. // --------------------------------------------------------------------------------------------------------------
  911.  
  912. void PICTGetFileTypes(OSType * pFileTypes, OSType * pDocumentTypes, short * numTypes)
  913. {
  914. #if ALLOW_QUICKTIME
  915.     long version;    
  916. #endif
  917.  
  918.     pFileTypes[*numTypes]         = 'PICT';
  919.     pDocumentTypes[*numTypes]     = kPICTWindow;
  920.     (*numTypes)++;
  921.  
  922. #if ALLOW_QUICKTIME
  923.     if( (Gestalt(gestaltQuickTime, &version) == noErr) && (version >= 0x03000000) )
  924.         {
  925.         pFileTypes[*numTypes]         = 'qtif';
  926.         pDocumentTypes[*numTypes]     = kPICTWindow;
  927.         (*numTypes)++;
  928.         }
  929. #endif
  930. } // PICTGetFileTypes
  931.